package com.qymerge.manage.system.service.impl;

import com.qymerge.manage.core.bean.ActionResultRO;
import com.qymerge.manage.core.constant.BaseConstants;
import com.qymerge.manage.core.enums.StatusTypes;
import com.qymerge.manage.core.utils.CommonUtil;
import com.qymerge.manage.core.utils.GsonUtil;
import com.qymerge.manage.core.utils.MD5Utils;
import com.qymerge.manage.core.utils.SHA256Enhanced;
import com.qymerge.manage.system.dao.*;
import com.qymerge.manage.system.dto.SysMenuDTO;
import com.qymerge.manage.system.dto.SysUserDTO;
import com.qymerge.manage.system.dto.SysUserSnapDTO;
import com.qymerge.manage.system.dto.SysUserSnapshotDTO;
import com.qymerge.manage.system.ro.*;
import com.qymerge.manage.system.ro.*;
import com.qymerge.manage.system.service.IUserService;
import com.qymerge.manage.system.dao.*;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 *<p>Title: UserService</p>
 *<p>Description: 系统用户业务</p>
 *
 *@Author cong.zhang
 *@Version 1.0.0
 *@Date 2020/7/27
 *@Time 11:14
 */
@Service
public class UserServiceImpl implements IUserService {

    @Autowired
    private ISysUserDao sysUserDao;
    @Autowired
    private ISysRoleDao sysRoleDao;

    @Autowired
    private ISysUserRoleDao sysUserRoleDao;
    @Autowired
    private ISysMenuRoleDao sysMenuRoleDao;
    @Autowired
    private ISysMenuDao sysMenuDao;
    @Autowired
    private ISysUserLoginDao sysUserLoginDao;


    /**
     * 检查用户是否存在
     *
     * @param user
     * @return
     */
    @Override
    public SysUserRO checkUser(SysUserRO user) {
        return sysUserDao.findOneByPhoneAndPassword(user.getPhone(), MD5Utils.md5Hex(user.getPassword() + BaseConstants.PWD_SIGN));
    }

    /**
     * 检查用户是否存在
     *
     * @param user
     * @return
     */
    @Override
    public SysUserSnapshotDTO checkUserSnapshot(SysUserRO user) {

        // 对密码进行sha256编码
        String passwordSha256= SHA256Enhanced.sha256(user.getPassword());
        SysUserRO userRO = sysUserDao.findOneByPhoneAndPassword(user.getPhone(), passwordSha256);

        SysUserSnapshotDTO snapshotDTO = null;
        if (userRO != null) {
            snapshotDTO = new SysUserSnapshotDTO();
            Long userId = userRO.getId();
            String cnName = userRO.getCn_name();
            String password = userRO.getPassword();
            Integer status = userRO.getStatus();
            String company_id = userRO.getCompany_id();
            String company_code = userRO.getCompany_code();
            String company_name = userRO.getCompany_name();

            snapshotDTO.setUid(userId);
            snapshotDTO.setCn_name(cnName);
            snapshotDTO.setToken(password);
            snapshotDTO.setStatus(status);
            snapshotDTO.setCompany_id(company_id);
            snapshotDTO.setCompany_code(company_code);
            snapshotDTO.setCompany_name(company_name);

            // 查询用户角色信息
            SysRoleRO roleRO = sysRoleDao.findOneByUserId(userId);
            if (roleRO != null) {
                snapshotDTO.setRoid_id(roleRO.getId());
                snapshotDTO.setRoid_name(roleRO.getRole_name());
            } else {
                snapshotDTO.setRoid_id(0L);
                snapshotDTO.setRoid_name("相关角色权限已被下线，请联系管理员处理");
            }

            // 插入用户成功登录信息
            sysUserLoginDao.install(new SysUserLogin(user.getPhone(), StatusTypes.OnLine.getStatus()));
            // 更新用户的登录错误累计清零
            if (userRO.getLoginCount() > 0) {
                sysUserDao.updateUserLoginCountZero(userRO.getId());
            }
        } else {
            sysUserLoginDao.install(new SysUserLogin(user.getPhone(), StatusTypes.OffLine.getStatus()));
            SysUserRO userDaoOneByPhone = sysUserDao.findOneByPhone(user.getPhone());

            if (userDaoOneByPhone != null) {
                if (userDaoOneByPhone.getLoginCount() < 5) {
                    sysUserDao.updateUserLoginCount(userDaoOneByPhone.getId());
                } else if (userDaoOneByPhone.getLoginCount() >= 5) {
                    // 禁用用户登录
                    sysUserDao.updateStatus(userDaoOneByPhone.getId(), StatusTypes.OffLine.getStatus());
                    snapshotDTO = new SysUserSnapshotDTO();
                    snapshotDTO.setStatus(StatusTypes.OffLine.getStatus());
                }
            }
        }

        return snapshotDTO;
    }

    /**
     * 检查密码是否正确
     *
     * @param sysUser
     * @return
     */
    @Override
    public SysUserRO checkPassword(SysUserRO sysUser) {
        if (sysUser == null || StringUtils.isEmpty(sysUser.getPassword())) {
            return null;
        }
        return sysUserDao.checkPassword(sysUser.getId(), MD5Utils.md5Hex(sysUser.getPassword() + BaseConstants.PWD_SIGN));
    }

    /**
     * 编辑密码
     *
     * @param user
     * @return
     */
    @Override
    public boolean editUserPwd(SysUserDTO user) {
        String newPass = MD5Utils.md5Hex(user.getNewPass() + BaseConstants.PWD_SIGN);
        try {
            int rn = sysUserDao.updatePwd(user.getId(), newPass);
            return rn > 0 ? true:false;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 编辑密码
     *
     * @param user
     * @return
     */
    @Override
    public ActionResultRO resetUserPwd(SysUserDTO user) {
        // 获取随机密码
        String password = CommonUtil.generatePassword(12);
        // 设置密码sha256编码
        String newPass = SHA256Enhanced.sha256(password);

        int rn = sysUserDao.updatePwd(user.getId(), newPass);
        return new ActionResultRO(rn > 0, "重置密码成功,您的密码为：" + password, "重置密码失败");
    }

    /**
     * 格式化菜单数据
     *
     * @param userId
     * @return
     */
    @Override
    public List<SysMenuDTO> getMenuByUser(long userId) {
        //1、根据userId 从sys_user_role表中获取roleIds
        List<SysUserRoleRO> userRoleROS = sysUserRoleDao.findAllRoleByIds(userId);

        // 获取所有的角色信息ID
        Set<Long> roleIds = new HashSet<Long>();
        // 获取所有的菜单信息ID
        Set<Long> menuIds = new HashSet<Long>();

        List<SysMenuDTO> menus = null;

        if (!CollectionUtils.isEmpty(userRoleROS)) {
            for (SysUserRoleRO userRole : userRoleROS) {
                roleIds.add(userRole.getRole_id());
            }

            // 2、根据role_id 从获取sys_menu_role表中获取menuIds
            List<SysMenuRoleRO> menuRoleROS = sysMenuRoleDao.findAllByIds(roleIds);

            if (!CollectionUtils.isEmpty(menuRoleROS)) {
                for (SysMenuRoleRO menuRole : menuRoleROS) {
                    menuIds.add(menuRole.getMenu_id());
                }

                //3、根据menu_id 从sys_menu表中获取菜单详情
                List<SysMenuRO> menuROS = sysMenuDao.findAllByIds(menuIds);

                if (!CollectionUtils.isEmpty(menuROS)) {
                    menus = new ArrayList<SysMenuDTO>();

                    for (SysMenuRO menu : menuROS) {
                        SysMenuDTO dto = new SysMenuDTO();
                        dto.setId(menu.getId());
                        dto.setParent_id(menu.getParent_id());
                        dto.setMenu_name(menu.getMenu_name());
                        dto.setMenu_path(menu.getMenu_path());
                        dto.setMenu_sort(menu.getMenu_sort());
                        dto.setIcon_cls(menu.getIcon_cls());
                        menus.add(dto);
                    }
                }
            }
        }

        return menus;
    }

    /**
     * 格式化菜单列表
     *
     * @param menuDtoList
     * @return
     */
    @Override
    public String formatMenuJson(List<SysMenuDTO> menuDtoList) {
        // 1. 定义格式化接收
        List<SysMenuDTO> treeList = new ArrayList<SysMenuDTO>();

        List<Long> idList = new ArrayList<Long>();
        if (!CollectionUtils.isEmpty(menuDtoList)) {
            // 1. 获取所有的菜单ids
            for (SysMenuDTO dto : menuDtoList) {
                idList.add(dto.getId());
            }

            // 2. 判断菜单中的父ID，用户封装子类数据
            for (SysMenuDTO dto : menuDtoList) {
                if (!idList.contains(dto.getParent_id())) {
                    List<SysMenuDTO> childList = getRecursionChildList(menuDtoList, dto.getId());
                    dto.setChildren(childList);
                    treeList.add(dto);
                }
            }
        }
        // 排序
        Collections.sort(treeList);
        // 格式化为json字符串返回
        return GsonUtil.t2Json2(treeList);
    }

    /**
     * 根据父ID 寻找子类数据
     *
     * @param dataList    数据集
     * @param parentId    父ID
     * @return
     */
    @Override
    public List<SysMenuDTO> getRecursionChildList(List<SysMenuDTO> dataList, long parentId) {
        // 1.定义子类集合
        List<SysMenuDTO> childList = new ArrayList<SysMenuDTO>();

        if (!CollectionUtils.isEmpty(dataList)) {
            for (SysMenuDTO dto : dataList) {
                if (String.valueOf(parentId).equals(String.valueOf(dto.getParent_id()))) {
                    dto.setChildren(getRecursionChildList(dataList, dto.getId()));
                    childList.add(dto);
                }
            }
        }
        // 排序
        Collections.sort(childList);
        // 返回
        return childList;
    }

    /**
     * 获取哦用户细信息
     *
     * @param userRO
     * @return
     */
    @Override
    public SysUserSnapDTO getSysUser(SysUserRO userRO) {
        SysUserRO sysUserRO = sysUserDao.findOneById(userRO.getId());
        if (null == sysUserRO) {
            return null;
        }else  {
            SysUserSnapDTO userSnapDTO = new SysUserSnapDTO();

            userSnapDTO.setId(sysUserRO.getId());
            userSnapDTO.setCn_name(sysUserRO.getCn_name());
            userSnapDTO.setUsername(sysUserRO.getUsername());
            userSnapDTO.setPhone(sysUserRO.getPhone());
            userSnapDTO.setWechat_id(sysUserRO.getWechat_id());

            userSnapDTO.setToken(sysUserRO.getPassword());

            userSnapDTO.setCompany_id(sysUserRO.getCompany_id());
            userSnapDTO.setCompany_code(sysUserRO.getCompany_code());
            userSnapDTO.setCompany_name(sysUserRO.getCompany_name());

            userSnapDTO.setStatus(sysUserRO.getStatus());
            userSnapDTO.setCreate_time(sysUserRO.getCreate_time());

            return userSnapDTO;
        }
    }


}
